package bsp;

import org.apache.hadoop.io.Writable;
import org.apache.hama.bsp.BSPPeer;
import org.apache.hama.bsp.TaskAttemptID;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hama.bsp.Counters.Counter;
import org.apache.hama.bsp.sync.SyncException;
import org.apache.hama.util.KeyValuePair;

public interface Context<K1, V1, K2, V2, M extends Writable> extends
		BSPPeer<K1, V1, K2, V2, M> {

	/**
	 * Clears all queues entries.
	 */
	@Override
	public void clear();

	/**
	 * @return the names of all the peers executing tasks from the same job
	 *         (including this peer).
	 */
	@Override
	public String[] getAllPeerNames();

	/**
	 * @return the jobs configuration
	 */
	@Override
	public Configuration getConfiguration();

	/**
	 * Get the {@link Counter} of the given group with the given name.
	 * 
	 * @param name
	 *            counter name
	 * @return the <code>Counter</code> of the given group/name.
	 */
	@Override
	public Counter getCounter(Enum<?> name);

	/**
	 * Get the {@link Counter} of the given group with the given name.
	 * 
	 * @param group
	 *            counter group
	 * @param name
	 *            counter name
	 * @return the <code>Counter</code> of the given group/name.
	 */
	@Override
	public Counter getCounter(String group, String name);

	/**
	 * @return A message from the peer's received messages queue (a FIFO).
	 * @throws IOException
	 */
	@Override
	public M getCurrentMessage() throws IOException;

	/**
	 * @return The number of messages in the peer's received messages queue.
	 */
	@Override
	public int getNumCurrentMessages();

	/**
	 * @return the number of peers
	 */
	@Override
	public int getNumPeers();

	/**
	 * @return the index of this peer from sorted array by name.
	 */
	@Override
	public int getPeerIndex();

	/**
	 * @return the name of this peer in the format "hostname:port".
	 */
	@Override
	public String getPeerName();

	/**
	 * @return the name of n-th peer from sorted array by name.
	 */
	@Override
	public String getPeerName(int index);

	/**
	 * @return the current position of the file read pointer
	 * @throws IOException
	 */
	@Override
	public long getPos() throws IOException;

	/**
	 * @return the size of assigned split
	 */
	@Override
	public long getSplitSize();

	/**
	 * @return the count of current super-step
	 */
	@Override
	public long getSuperstepCount();

	/**
	 * @return the task id of this task.
	 */
	@Override
	public TaskAttemptID getTaskId();

	/**
	 * Increments the counter identified by the key, which can be of any
	 * {@link Enum} type, by the specified amount.
	 * 
	 * @param key
	 *            key to identify the counter to be incremented. The key can be
	 *            be any <code>Enum</code>.
	 * @param amount
	 *            A non-negative amount by which the counter is to be
	 *            incremented.
	 */
	@Override
	public void incrementCounter(Enum<?> key, long amount);

	/**
	 * Increments the counter identified by the group and counter name by the
	 * specified amount.
	 * 
	 * @param group
	 *            name to identify the group of the counter to be incremented.
	 * @param counter
	 *            name to identify the counter within the group.
	 * @param amount
	 *            A non-negative amount by which the counter is to be
	 *            incremented.
	 */
	@Override
	public void incrementCounter(String group, String counter, long amount);

	/**
	 * Reads the next key value pair and returns it as a pair. It may reuse a
	 * {@link KeyValuePair} instance to save garbage collection time.
	 * 
	 * @return null if there are no records left.
	 * @throws IOException
	 */
	@Override
	public KeyValuePair<K1, V1> readNext() throws IOException;

	/**
	 * Deserializes the next input key value into the given objects.
	 * 
	 * @param key
	 * @param value
	 * @return false if there are no records to read anymore
	 * @throws IOException
	 */
	@Override
	public boolean readNext(K1 key, V1 value) throws IOException;

	/**
	 * Closes the input and opens it right away, so that the file pointer is at
	 * the beginning again.
	 */
	@Override
	public void reopenInput() throws IOException;

	/**
	 * Send a data with a tag to another BSPSlave corresponding to hostname.
	 * Messages sent by this method are not guaranteed to be received in a sent
	 * order.
	 * 
	 * @param peerName
	 * @param msg
	 * @throws IOException
	 */
	@Override
	public void send(String peerName, M msg) throws IOException;

	/**
	 * Barrier Synchronization.
	 * 
	 * Sends all the messages in the outgoing message queues to the
	 * corresponding remote peers.
	 * 
	 * @throws IOException
	 * @throws SyncException
	 * @throws InterruptedException
	 */
	@Override
	public void sync() throws IOException, SyncException, InterruptedException;

	/**
	 * Writes a key/value pair to the output collector.
	 * 
	 * @param key
	 *            your key object
	 * @param value
	 *            your value object
	 * @throws IOException
	 */
	@Override
	public void write(K2 key, V2 value) throws IOException;
}
